﻿using System;
using System.Web.Mvc;
using RuTracker.Interface;
using RuTracker.Interface.Dropbox;
using RuTracker.MVC.Core;
using RuTracker.MVC.Models.Settings;
using RuTrackerLib;

namespace RuTracker.MVC.Controllers
{
    [Authorize]
    public class SettingsController : Controller
    {
        public ActionResult Index()
        {
            return View(CreateModel());
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Index(SettingsModel model)
        {
            model.UserName = User.Identity.Name;

            if (!ModelState.IsValid)
                return View(model);

            IUserRepository userRepository = Container.Current.Resolve<IUserRepository>();
            User user = userRepository.GetUser(User.Identity.Name);
            UserStorageInfo storage = userRepository.GetUserStorageInfo(User.Identity.Name) ?? new UserStorageInfo();

            user.EMail = model.EMail;

            userRepository.UpdateUser(user);
            userRepository.SetUserStorageInfo(user.Name, storage.StorageFolder, storage.Token == null ? null : storage.Token.ToArray());

            return Redirect("Default");
        }

        public ActionResult SelectDropboxFolder(string id)
        {
            if (string.IsNullOrEmpty(id))
                return ShowFolders();

            return ProcessSelection(id);
        }


        public ActionResult GetDropboxAccess()
        {
            DropboxAdapter adapter = new DropboxAdapter(Session);
            adapter.Reset();
            string url = adapter.RequestForToken(string.Format("{0}/LoginToDropbox", Request.Url.ToString().Replace("/GetDropboxAccess", string.Empty)));
            if (string.IsNullOrEmpty(url))
                return RedirectToAction("LoginToDropboxFailed");

            return Redirect(url);
        }

        public ActionResult LoginToDropboxFailed()
        {
            return View();
        }

        public ActionResult LoginToDropbox()
        {
            IUserRepository userRepository = Container.Current.Resolve<IUserRepository>();
            UserStorageInfo storage = userRepository.GetUserStorageInfo(User.Identity.Name) ?? new UserStorageInfo();
            DropboxAdapter adapter = new DropboxAdapter(Session);

            if (!adapter.Login())
                return RedirectToAction("LoginToDropboxFailed");

            userRepository.SetUserStorageInfo(User.Identity.Name, storage.StorageFolder, adapter.Token);
            adapter.Reset();
            return RedirectToAction("Index");
        }

        private ActionResult ShowFolders()
        {
            IUserRepository userRepository = Container.Current.Resolve<IUserRepository>();
            UserStorageInfo storage = userRepository.GetUserStorageInfo(User.Identity.Name);

            if (storage.Token == null || storage.Token.ToArray().Length == 0)
                return RedirectToAction("GetDropboxAccess");

            DropboxAdapter adapter = new DropboxAdapter(Session, storage.Token.ToArray());
            return View(adapter.ResolveStorageFolder());
        }

        private ActionResult ProcessSelection(string decodedFolderName)
        {
            string folderPath = StringEncryptor.Decrypt(decodedFolderName);
            IUserRepository userRepository = Container.Current.Resolve<IUserRepository>();
            UserStorageInfo storage = userRepository.GetUserStorageInfo(User.Identity.Name) ?? new UserStorageInfo();

            DropboxAdapter adapter = new DropboxAdapter(Session, storage.Token.ToArray());
            StorageFolder folder = adapter.ResolveStorageFolder().GetChild(folderPath) as StorageFolder;
            if (folder == null)
                throw new NotSupportedException("Invalid folder name");
            
            userRepository.SetUserStorageInfo(User.Identity.Name, folderPath, storage.Token.ToArray());
            return RedirectToAction("Index");
        }

        private SettingsModel CreateModel()
        {
            IUserRepository userRepository = Container.Current.Resolve<IUserRepository>();
            User user = userRepository.GetUser(User.Identity.Name);
            UserStorageInfo storage = userRepository.GetUserStorageInfo(User.Identity.Name);

            return new SettingsModel(user, storage);
        }
    }
}
